package Compiler;
import java.util.*;

public class Syntax implements SyntaxAnalyzer {
	String currentToken;
    @Override
//the start of the lola
    public void lola(LinkedList a) {
            
            if(!Compiler.Token.equalsIgnoreCase(Terminal.DOC_BEGIN)) {
                    System.err.println("SYNTAX ERROR: not correct Token"
                                                            + Compiler.Token + "when " + Terminal.DOC_BEGIN
                                                            + " was expected.");
                    System.exit(0);
            }
            a.add(new Terminal(Compiler.Token));
            
            
            currentToken = Compiler.Lexer.getNextToken(); 
            
            if (currentToken.equalsIgnoreCase(Terminal.BEGIN))
            {
                        define(a);
                        currentToken = Compiler.Lexer.getNextToken(); 
            }
            
            if (currentToken.equalsIgnoreCase(Terminal.COMMENT_BEGIN))
            {
                        comment(a);
                        currentToken = Compiler.Lexer.getNextToken(); 
            }
            
            if(currentToken.equalsIgnoreCase(Terminal.HEAD_BEGIN))
            {
                    head(a);
                    currentToken = Compiler.Lexer.getNextToken(); 
            }
            
            
            while(!currentToken.equalsIgnoreCase(Terminal.DOC_END)){
                
                if(currentToken.equalsIgnoreCase(Terminal.COMMENT_BEGIN))
                    comment(a);
                else if (currentToken.equalsIgnoreCase(Terminal.PARA_BEGIN))
                    paragraph(a);
                else if (currentToken.equalsIgnoreCase(Terminal.BOLD_BEGIN))
                    bold(a);
                else if (currentToken.equalsIgnoreCase(Terminal.ITALICS_BEGIN))
                    italics(a);
                else if (currentToken.equalsIgnoreCase(Terminal.LIST_BEGIN))
                    list(a);
                else
                    innerText(a);               
                currentToken = Compiler.Lexer.getNextToken();
            }               
            if(!currentToken.equalsIgnoreCase(Terminal.DOC_END)) {
                    System.err.println("SYNTAX ERROR: not correct Token"
                                                            + Compiler.Token + "when " + Terminal.DOC_END
                                                            + " was expected.");
                    System.exit(0);
            }
            a.add(new Terminal(currentToken));
            
            if(Compiler.Lexer.moreChar())
            {
               System.err.println("There is more after " + Terminal.DOC_END);
               System.exit(0);
            }
            //check to make sure there is nothing else after        
                    
    }

    @Override
    public void comment(LinkedList a) {

        a.add(new Terminal(currentToken));
        
        currentToken = Compiler.Lexer.getNextToken();
        a.add(new Terminal(currentToken));
        
        currentToken = Compiler.Lexer.getNextToken(); 
        if(!currentToken.equalsIgnoreCase(Terminal.COMMENT_END)) {
            System.err.println("SYNTAX ERROR: not correct Token '"
                                    + currentToken + "' when " + Terminal.COMMENT_END
                                    + " was expected.");
                    System.exit(0);
        }
        a.add(new Terminal(currentToken));    
    }

    @Override
    public void head(LinkedList a) {
        a.add(new Terminal(currentToken));
        
        currentToken = Compiler.Lexer.getNextToken();
        if(!currentToken.equalsIgnoreCase(Terminal.TITLE_BEGIN)) {
            System.err.println("SYNTAX ERROR: not correct Token "
                                    + currentToken + " when " + Terminal.TITLE_BEGIN
                                    + " was expected.");
            System.exit(0);
        }
        
        title(a);

        currentToken = Compiler.Lexer.getNextToken();
        if(!currentToken.equalsIgnoreCase(Terminal.REST_END)) {
            System.err.println("SYNTAX ERROR: not correct Token"
                                    + currentToken + "when " + Terminal.REST_END
                                    + " was expected.");
            System.exit(0);
        }
        a.add(new Terminal(currentToken));
    }

    @Override
    public void title(LinkedList a) {
        a.add(new Terminal(currentToken));
        
        currentToken = Compiler.Lexer.getNextToken();
        a.add(new Terminal(currentToken));
        
        currentToken = Compiler.Lexer.getNextToken(); 
        if(!currentToken.equalsIgnoreCase(Terminal.SECOND_END)) {
            System.err.println("SYNTAX ERROR: not correct Token '"
                                    + currentToken + "' when " + Terminal.SECOND_END
                                    + " was expected.");
            System.exit(0);
        }
        a.add(new Terminal(currentToken));
    }

    @Override
    public void paragraph(LinkedList a) {
        a.add(new Terminal(currentToken));
        currentToken = Compiler.Lexer.getNextToken();
        
        if(currentToken.equalsIgnoreCase(Terminal.BEGIN))
            define(a);

        while(!currentToken.equalsIgnoreCase(Terminal.REST_END)){

            if(currentToken.equalsIgnoreCase(Terminal.NEWLINE))
                a.add(new Terminal(currentToken));
            else innerLP(a);
            currentToken = Compiler.Lexer.getNextToken();                
        } 
        a.add(new Terminal(currentToken));
    }

    @Override
    public void bold(LinkedList a) {
        a.add(new Terminal(currentToken));
        
        currentToken = Compiler.Lexer.getNextToken();
        
        if(currentToken.equalsIgnoreCase(Terminal.BEGIN))
            define(a);
        else innerText(a);
        
        currentToken = Compiler.Lexer.getNextToken(); 
        if(!currentToken.equalsIgnoreCase(Terminal.SECOND_END)) {
            System.err.println("SYNTAX ERROR: not correct Token '"
                                    + currentToken + "' when " + Terminal.SECOND_END
                                    + " was expected.");
            System.exit(0);
        }
        a.add(new Terminal(currentToken));
    }

    @Override
    public void italics(LinkedList a) {
        a.add(new Terminal(currentToken));
        
        currentToken = Compiler.Lexer.getNextToken();
        
        if(currentToken.equalsIgnoreCase(Terminal.BEGIN))
            define(a);
        else innerText(a);
        
        currentToken = Compiler.Lexer.getNextToken(); 
        if(!currentToken.equalsIgnoreCase(Terminal.SECOND_END)) {
            System.err.println("SYNTAX ERROR: not correct Token '"
                                    + currentToken + "' when " + Terminal.SECOND_END
                                    + " was expected.");
            System.exit(0);
        }
        a.add(new Terminal(currentToken));
    }

    @Override
    public void list(LinkedList a) {           
        a.add(new Terminal(currentToken));
        currentToken = Compiler.Lexer.getNextToken();           
        while(!currentToken.equalsIgnoreCase(Terminal.REST_END)){

            if(!currentToken.equalsIgnoreCase(Terminal.ITEM_BEGIN)) {
                System.err.println("SYNTAX ERROR: not correct Token '"
                                        + currentToken + "' when " + Terminal.ITEM_BEGIN
                                        + " was expected.");
                System.exit(0);
            }           
            item(a);
            currentToken = Compiler.Lexer.getNextToken();                
        } 
        a.add(new Terminal(currentToken));
    }

    @Override
    public void item(LinkedList a) {
        a.add(new Terminal(currentToken));

        currentToken = Compiler.Lexer.getNextToken();           
        while(!currentToken.equalsIgnoreCase(Terminal.SECOND_END))
        {
            innerLP(a);
            currentToken = Compiler.Lexer.getNextToken();
        }
        a.add(new Terminal(currentToken));
    }

    @Override
    public void audio(LinkedList a) {
        a.add(new Terminal(currentToken));
        
        currentToken = Compiler.Lexer.getNextToken();
        a.add(new Terminal(currentToken));
        
        currentToken = Compiler.Lexer.getNextToken(); 
        if(!currentToken.equalsIgnoreCase(Terminal.SECOND_END)) {
            System.err.println("SYNTAX ERROR: not correct Token '"
                                    + currentToken + "' when " + Terminal.SECOND_END
                                    + " was expected.");
            System.exit(0);
        }
        a.add(new Terminal(currentToken));
    }

    @Override
    public void video(LinkedList a) {
        a.add(new Terminal(currentToken));
        
        currentToken = Compiler.Lexer.getNextToken();
        a.add(new Terminal(currentToken));
        
        currentToken = Compiler.Lexer.getNextToken(); 
        if(!currentToken.equalsIgnoreCase(Terminal.SECOND_END)) {
            System.err.println("SYNTAX ERROR: not correct Token '"
                                    + currentToken + "' when " + Terminal.SECOND_END
                                    + " was expected.");
            System.exit(0);
        }
        a.add(new Terminal(currentToken));
    }

    @Override
    public void define(LinkedList a) {
        a.add(new Terminal(currentToken));
        
        currentToken = Compiler.Lexer.getNextToken();
        a.add(new Terminal(currentToken));
        
        currentToken = Compiler.Lexer.getNextToken(); 
        if(!currentToken.equalsIgnoreCase(Terminal.MID)) {
            System.err.println("SYNTAX ERROR: not correct Token '"
                                    + currentToken + "' when " + Terminal.MID
                                    + " was expected.");
            System.exit(0);
        }
        a.add(new Terminal(currentToken));
        
        currentToken = Compiler.Lexer.getNextToken();
        a.add(new Terminal(currentToken));

        currentToken = Compiler.Lexer.getNextToken();
        if(!currentToken.equalsIgnoreCase(Terminal.SECOND_END)) {
            System.err.println("SYNTAX ERROR: not correct Token '"
                                    + currentToken + "' when " + Terminal.SECOND_END
                                    + " was expected.");
            System.exit(0);
        }
        a.add(new Terminal(currentToken));
    }

    @Override
    public void use(LinkedList a) {
        a.add(new Terminal(currentToken));
        
        currentToken = Compiler.Lexer.getNextToken();
        a.add(new Terminal(currentToken));
        
        currentToken = Compiler.Lexer.getNextToken(); 
        if(!currentToken.equalsIgnoreCase(Terminal.SECOND_END)) {
            System.err.println("SYNTAX ERROR: not correct Token '"
                                    + currentToken + "' when " + Terminal.SECOND_END
                                    + " was expected.");
            System.exit(0);
        }
        a.add(new Terminal(currentToken));
    }

/**
 *
 * @param a
 */
public void innerLP(LinkedList a) {
        if(currentToken.equalsIgnoreCase(Terminal.BOLD_BEGIN))
            bold(a);
        else if (currentToken.equalsIgnoreCase(Terminal.ITALICS_BEGIN))
            italics(a);        
        else if (currentToken.equalsIgnoreCase(Terminal.LIST_BEGIN))
            list(a);
        else innerText(a);  
    }
    
/**
 *
 * @param a
 */
public void innerText(LinkedList a){
        if(currentToken.equalsIgnoreCase(Terminal.CALL))
            use(a);
        else if (currentToken.equalsIgnoreCase(Terminal.SOUND_BEGIN))
            audio(a);        
        else if (currentToken.equalsIgnoreCase(Terminal.VIDEO_BEGIN))
            video(a);
        else if (currentToken.equalsIgnoreCase(Terminal.NEWLINE))
            a.add(new Terminal(currentToken));
        else 
            a.add(new Terminal(currentToken));
    }
    
    
}
